/*
 *  Copyright (C) 2005-2007 Renier Roth
 *  www.renier.de
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package de.renier.vdr.channel.editor.util;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;

import de.renier.vdr.channel.Channel;
import de.renier.vdr.channel.ChannelCategory;
import de.renier.vdr.channel.ChannelElement;
import de.renier.vdr.channel.editor.container.ChannelListRenderer;

/**
 * Utils
 * 
 * @author <a href="mailto:editor@renier.de">Renier Roth</a>
 */
public class Utils {

  public static final ImageIcon iconRoot = new ImageIcon(ChannelListRenderer.class
      .getResource("/org/javalobby/icons/16x16/DatePicker.gif"));
  public static final ImageIcon iconCategory = new ImageIcon(Utils.class
      .getResource("/org/javalobby/icons/20x20/Folder.gif"));

  public static ImageIcon iconRadio = null;
  public static ImageIcon iconRadioCrypt = null;
  public static ImageIcon iconTelevision = null;
  public static ImageIcon iconTelevisionCrypt = null;
  public static ImageIcon iconService = null;
  public static ImageIcon iconServiceCrypt = null;

  private final static String ICONPATH_PREFIX = "/de/renier/vdr/channel/editor/images/";
  private final static String ICONNAME_RADIO = "/radio.png";
  private final static String ICONNAME_RADIOCRYPT = "/radio-decrypted.png";
  private final static String ICONNAME_VIDEO = "/video.png";
  private final static String ICONNAME_VIDEOCRYPT = "/video-decrypted.png";
  private final static String ICONNAME_SERVICE = "/service.png";
  private final static String ICONNAME_SERVICECRYPT = "/service-decrypted.png";

  /**
   * static initializer
   */
  static {
    String iconsetName = LocalProperties.getInstance().getProperty(LocalProperties.PROP_ICONSET);
    Utils.changeChannelIconSet(iconsetName);
  }

  /**
   * isEmpty
   * 
   * @param input
   * @return
   */
  public static boolean isEmpty(String input) {
    if (input != null && input.length() > 0) { return false; }
    return true;
  }

  /**
   * buildChannelTree
   * 
   * @param input
   * @param listName
   * @return
   */
  public static DefaultMutableTreeNode buildChannelTree(Reader input, String listName) {
    DefaultMutableTreeNode ret = new DefaultMutableTreeNode(new ChannelElement(listName));
    DefaultMutableTreeNode lastCategory = null;
    int in = 0;
    StringBuffer inputBuffer = new StringBuffer();
    String inputLine = null;
    try {
      while ((in = input.read()) >= 0) {
        if (in == 10) {
          inputLine = inputBuffer.toString();
          lastCategory = putChannelElementIntoTree(ret, lastCategory, inputLine);
          // clear buffer
          inputBuffer.setLength(0);
        } else {
          inputBuffer.append((char) in);
        }
      }
      // last line from buffer
      inputLine = inputBuffer.toString();
      if (!isEmpty(inputLine)) {
        lastCategory = putChannelElementIntoTree(ret, lastCategory, inputLine);
      }
      input.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return ret;
  }

  /**
   * buildAliasMap
   * 
   * @param input
   * @return
   */
  public static Map buildAliasMap(Reader input) {
    Map ret = new HashMap();
    int in = 0;
    StringBuffer inputBuffer = new StringBuffer();
    String inputLine = null;
    try {
      while ((in = input.read()) >= 0) {
        if (in == 10) {
          inputLine = inputBuffer.toString();
          // split key and alias
          int splitPos = inputLine.indexOf(":");
          if (splitPos > 0) {
            ret.put(inputLine.substring(0, splitPos), inputLine.substring(splitPos + 1));
          }
          // clear buffer
          inputBuffer.setLength(0);
        } else {
          if (in != 13) inputBuffer.append((char) in);
        }
      }
      // last line from buffer
      inputLine = inputBuffer.toString();
      // split key and alias
      int splitPos = inputLine.indexOf(":");
      if (splitPos > 0) {
        ret.put(inputLine.substring(0, splitPos), inputLine.substring(splitPos + 1));
      }
      input.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return ret;
  }

  /**
   * putChannelElementIntoTree
   * 
   * @param ret
   * @param lastCategory
   * @param inputLine
   * @return
   */
  private static DefaultMutableTreeNode putChannelElementIntoTree(DefaultMutableTreeNode root,
      DefaultMutableTreeNode lastCategory, String inputLine) {
    ChannelElement tempChannelelement;
    tempChannelelement = convertStringToChannelElement(inputLine);
    if (tempChannelelement instanceof ChannelCategory) {
      lastCategory = new DefaultMutableTreeNode(tempChannelelement);
      root.add(lastCategory);
    } else {
      if (lastCategory == null) {
        root.add(new DefaultMutableTreeNode(tempChannelelement));
      } else {
        lastCategory.add(new DefaultMutableTreeNode(tempChannelelement));
      }
    }
    return lastCategory;
  }

  /**
   * Output Channel List
   * 
   * @param output
   * @param rootNode
   * @throws IOException
   */
  public static void outputChannelTree(Writer output, DefaultMutableTreeNode rootNode) throws IOException {
    Enumeration enumer = rootNode.preorderEnumeration();
    while (enumer.hasMoreElements()) {
      ChannelElement channelElement = (ChannelElement) ((DefaultMutableTreeNode) enumer.nextElement()).getUserObject();
      if (channelElement != null) {
        output.write(channelElement.outputString());
      }
    }
    output.flush();
    output.close();
  }

  /**
   * convertStringToChannelElement
   * 
   * @param line
   * @return
   */
  public static ChannelElement convertStringToChannelElement(String line) {
    ChannelElement ret = null;
    // trim line
    line = line.trim();
    // check type
    if (line.startsWith(":")) {
      ret = new ChannelCategory(line.substring(1));
    } else {
      // split line
      StringTokenizer st = new StringTokenizer(line, ":");
      int tokens = st.countTokens();
      if (tokens >= 13) {
        Channel channel = new Channel(st.nextToken());
        channel.setFrequenz(st.nextToken());
        channel.setParameter(st.nextToken());
        channel.setSource(st.nextToken());
        channel.setSymbolrate(st.nextToken());
        channel.setVPid(st.nextToken());
        channel.setAPid(st.nextToken());
        channel.setTPid(st.nextToken());
        channel.setCaId(st.nextToken());
        channel.setSid(st.nextToken());
        channel.setNid(st.nextToken());
        channel.setTid(st.nextToken());
        channel.setRid(st.nextToken());
        ret = channel;
      }
    }
    return ret;
  }

  public static List getLastOpenedFiles() {
    List files = new LinkedList();
    for (int i = 0; i < ChannelConstants.LAST_OPENFILE_COUNT; i++) {
      String lastfile = LocalProperties.getInstance().getProperty(LocalProperties.PROP_LASTFILE_PREFIX + i);
      if (!Utils.isEmpty(lastfile)) {
        files.add(new File(lastfile));
      }
    }
    return files;
  }

  public static void setLastOpenedFile(File file) {
    List files = getLastOpenedFiles();
    // remove preview existing file
    files.remove(file);
    // add last file on top of list
    files.add(0, file);
    // save to LocalProperties
    Iterator it = files.iterator();
    int counter = 0;
    while (it.hasNext()) {
      // break if we reache maximum
      if (counter == ChannelConstants.LAST_OPENFILE_COUNT) {
        break;
      }
      // store filepath to property
      File tempFile = (File) it.next();
      LocalProperties.getInstance().setProperty(LocalProperties.PROP_LASTFILE_PREFIX + counter,
                                                tempFile.getAbsolutePath());
      counter++;
    }
    // store properties
    LocalProperties.getInstance().storeLocalProps();
  }

  public static void changeChannelIconSet(String iconset) {
    if (iconset != null) {
      URL tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_RADIO);
      if (tempUrl != null) {
        iconRadio = new ImageIcon(tempUrl);
      }
      tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_RADIOCRYPT);
      if (tempUrl != null) {
        iconRadioCrypt = new ImageIcon(tempUrl);
      }
      tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_VIDEO);
      if (tempUrl != null) {
        iconTelevision = new ImageIcon(tempUrl);
      }
      tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_VIDEOCRYPT);
      if (tempUrl != null) {
        iconTelevisionCrypt = new ImageIcon(tempUrl);
      }
      tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_SERVICE);
      if (tempUrl != null) {
        iconService = new ImageIcon(tempUrl);
      }
      tempUrl = Utils.class.getResource(ICONPATH_PREFIX + iconset + ICONNAME_SERVICECRYPT);
      if (tempUrl != null) {
        iconServiceCrypt = new ImageIcon(tempUrl);
      }
    }
  }
}
